package com.yc.tomcat.impl;

import com.yc.tomcat.*;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;

public class TomcatImpl implements Tomcat {

    // 网站根目录
    public static final String WEBROOT = "D:/_文件柜/133/0926/大麦商城";
    // servlet 容器
    public Map<String, HttpServlet> servletMap = new HashMap<>();

    public static void main(String[] args) throws IOException {
        TomcatImpl tomcat = new TomcatImpl();
        tomcat.start(8080);
    }

    @Override
    public void start(int port) throws IOException {
        ServerSocket server = new ServerSocket(port);
        System.out.println("服务器启动成功:" + port);
        while (true) {
            System.out.println("监听浏览器的请求...");
            try(Socket socket = server.accept()) {
                HttpServletRequest request = buildRequest(socket);
                HttpServletResponse response = buildResponse(socket, request);

                // 服务扫描当前工程所有的类 => 注解 => 所有的Serlvet
                // 注册 Servlet , 默认情况下, servlet 应该是在第一次访问时被创建+注册
                servletMap.put("/hello.s", new HelloServlet());
                servletMap.put("/like.s", new LikesServlet());
                servletMap.put("/post.s", new PostServlet());
                servletMap.put("/toindex.s", new RedirectServlet());
                servletMap.put("/cookie.s", new CookieServlet());
                servletMap.put("/addCookie.s", new AddCookieServlet());
                servletMap.put("/login.s", new LoginServlet());
                servletMap.put("/getLoginedUser.s", new GetLoginedUserServlet());
                servletMap.put("/logout.s", new LogoutServlet());

                if (isServletRequest(request)) {
                    processServletRequest(request, response);
                } else if (isStaticRequest(request)) {
                    processStaticRequest(request, response);
                } else {
                    // 404 页面
                }
            } catch (Exception e) {
                // throw new RuntimeException(e);
                e.printStackTrace();
            }
        }

    }

    @Override
    public HttpServletRequest buildRequest(Socket socket) {
        try {
            return new HttpServletRequestImpl(socket);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public HttpServletResponse buildResponse(Socket socket, HttpServletRequest request) {
        return new HttpServletResponseImpl(socket, request);
    }

    @Override
    public boolean isStaticRequest(HttpServletRequest request) {
        String filepath = WEBROOT + request.getRequestURI();
        // 判断文件是否存在
        return new File(filepath).exists();
    }

    @Override
    public boolean isServletRequest(HttpServletRequest request) {
        // 判断servlet容器中是否包含该地址
        return servletMap.containsKey(request.getRequestURI());
    }

    @Override
    public boolean processStaticRequest(HttpServletRequest request, HttpServletResponse response) throws IOException {
        // 响应 hello world 页面
        OutputStream out = response.getOutputStream();
        // 响应头行
        out.write("HTTP/1.1 200 OK\n".getBytes());
        // 空行
        out.write("\n".getBytes());
        String filepath = WEBROOT + request.getRequestURI();
        try (FileInputStream fis = new FileInputStream(filepath)) {
            byte[] bytes = new byte[1024];
            int count;
            while ((count = fis.read(bytes)) > 0) {
                out.write(bytes, 0, count);
            }
        }
        return false;
    }

    @Override
    public boolean processServletRequest(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
        // 从容器中获取 servlet
        HttpServlet servlet = servletMap.get(request.getRequestURI());
        // 由 servlet 处理请求, 构建响应数据
        servlet.service(request, response);
        // 将响应的数据推送给浏览器
        response.flushBuffer();
        return false;
    }

    @Override
    public String getMimeType(String path) {
        return null;
    }

    @Override
    public HttpServlet getServlet(HttpServletRequest request) {
        return null;
    }

    @Override
    public void createSession(HttpServletRequest request, HttpServletResponse response) {

    }

    @Override
    public void stop() {

    }
}
